package com.gtm.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gtm.model.Group;
import com.gtm.model.Pager;
import com.gtm.model.User;
import com.gtm.repository.GroupRepository;
import com.gtm.repository.TopicRepository;
import com.gtm.repository.UserRepository;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.*;

/**
 * Created by ryan on 2017/12/5.
 */
@Service
public class GroupService extends BaseService<Group> {
    @Autowired
    MongoTemplate mt;

    @Autowired
    UserRepository usr;

    @Autowired
    GroupRepository gr;


    public Page<Group> listWithKeyMeta(PageRequest pageRequest, String searchKey) {
        if (searchKey==null) {
            return gr.findAll(pageRequest);
        }
        JSONObject sk= JSON.parseObject(searchKey);
        Set<String> keys=sk.keySet();
        Criteria inter=new Criteria();
        List<Criteria> listC=new ArrayList<Criteria>();
        for(String s:keys){
            String value=sk.get(s).toString();
            if (value==null)
                continue;
            if (s.equals("markedDel")) {
                listC.add(Criteria.where(s).is(Boolean.valueOf(value)));
            }
            else
                listC.add(Criteria.where(s).regex(value,"i"));
        }
        inter.andOperator(listC.stream().toArray(s->new Criteria[s]));
        List<Group> tps= mt.find(Query.query(inter).with(pageRequest),Group.class);
        long total = mt.count(Query.query(inter), Group.class);
        if(tps==null)
            return null;
//        PageImpl<Topic> page =new PageImpl<Topic>(tps,pageRequest,tps.size());
        @SuppressWarnings({ "unchecked", "rawtypes" })
        PageImpl<Group> page = new PageImpl(tps, pageRequest, total);
        return page;
    }

    public Group addGroup(String address, String host, Date date, String countType, String type, String record) {
        Group group=new Group();
        group.setAddress(address);
        group.setHost(host);
        group.setDate(date);
        group.setCountType(countType);
        group.setType(type);
        group=gr.save(group);//add
        JSONArray array= (JSONArray) JSONArray.parse(record);
        System.out.println(array.toString());
        List<DBObject> reclist=new ArrayList<DBObject>();
        List<String> teachers=new ArrayList<String>();
        List<String> students=new ArrayList<String>();
        Iterator<Object> it = array.iterator();
        while (it.hasNext()){
            JSONObject tmp=(JSONObject)it.next();
            System.out.println(tmp.toString());
            DBObject db=new BasicDBObject();
            String teacherName=tmp.get("teacherName").toString();
            String teacherId=tmp.get("teacherId").toString();
            String stuName=tmp.get("stuName").toString();
            String stuId=tmp.get("stuId").toString();
            String topicName=tmp.get("topicName").toString();
            String topicId=tmp.get("topicId").toString();
            User stu=usr.findOne(stuId);
            if(type.equals("0"))
                stu.setAdditionalData("state","GROUP_PENDING");
            else
                stu.setAdditionalData("state","GROUP1_PENDING");
            stu.setAdditionalData("groupId",group.getId());
            usr.save(stu);
            db.put("teacherName",teacherName);
            db.put("teacherId",teacherId);
            db.put("stuName",stuName);
            db.put("stuId",stuId);
            db.put("topicName",topicName);
            db.put("topicId",topicId);
            reclist.add(db);
            teachers.add(teacherId);
            students.add(stuId);
        }
        group.setRecord(reclist);
        group.setStuList(students);
        group.setTeacherList(teachers);
        return gr.save(group);
    }

    public List<User> listMyStu(String tid,String type) {
        Criteria cri=new Criteria();
        cri.where("record").elemMatch(Criteria.where("teacherId").is(tid)).and("type").is(type);
        List<Group> gplist=mt.find(Query.query(cri),Group.class);
        List<User> stuList=new ArrayList<User>();
        Aggregation aggregation =Aggregation.newAggregation(Aggregation.match(cri));
        AggregationResults<Group> aggr=mt.aggregate(aggregation,"group",Group.class);
        List<Group> gps=aggr.getMappedResults();
        for (Group gp:gps){
            System.out.println(gp.toString());
        }
        for (Group g:gplist){
            List<DBObject> reclist=g.getRecord();
            for (DBObject rec:reclist){
                if (rec.get("teacherId").toString().equals(tid)&&g.getType().equals(type)){
                    stuList.add(usr.findOne(rec.get("stuId").toString()));
                }
            }
        }
        return stuList;
    }

    public User audit(String sid, String grade, Boolean isPass) {
        User user=usr.findOne(sid);
        user.setAdditionalData("pro_grade",grade);
        switch (isPass.toString()){
            case "true":
                user.setAdditionalData("state","GROUP_PASS");
                break;
            case "false":
                user.setAdditionalData("state","PROPOSAL_PASS");
                break;
        }
        return usr.save(user);
    }

    public Group editGroup(String gid,String address, String host, Date date, String countType, String type, String record) {
        Group group=gr.findOne(gid);
        group.setAddress(address);
        group.setHost(host);
        group.setDate(date);
        group.setCountType(countType);
        group.setType(type);
        List<DBObject> records=group.getRecord();

        JSONArray array= (JSONArray) JSONArray.parse(record);
        System.out.println(array.toString());
        List<DBObject> reclist=new ArrayList<DBObject>();
        List<String> teachers=new ArrayList<String>();
        List<String> students=new ArrayList<String>();
        List<JSONObject> list=array.toJavaList(JSONObject.class);
        List<String> templist=new ArrayList<String>();
        for(JSONObject js:list){
            templist.add(js.get("stuId").toString());
        }
        for(DBObject obj:records){
            String sid=obj.get("stuId").toString();
            if (templist.contains(sid)==false){
                User user=usr.findOne(sid);
                user.setAdditionalData("state","PROPOSAL_PASS");
                user.setAdditionalData("groupId",null);
                usr.save(user);
            }
        }

        Iterator<Object> it = array.iterator();
        while (it.hasNext()){
            JSONObject tmp=(JSONObject)it.next();
            System.out.println(tmp.toString());
            DBObject db=new BasicDBObject();
            String teacherName=tmp.get("teacherName").toString();
            String teacherId=tmp.get("teacherId").toString();
            String stuName=tmp.get("stuName").toString();
            String stuId=tmp.get("stuId").toString();
            String topicName=tmp.get("topicName").toString();
            String topicId=tmp.get("topicId").toString();
            User stu=usr.findOne(stuId);
            stu.setAdditionalData("state","GROUP_PENDING");
            stu.setAdditionalData("groupId",group.getId());
            usr.save(stu);
            db.put("teacherName",teacherName);
            db.put("teacherId",teacherId);
            db.put("stuName",stuName);
            db.put("stuId",stuId);
            db.put("topicName",topicName);
            db.put("topicId",topicId);
            reclist.add(db);
            teachers.add(teacherId);
            students.add(stuId);
        }
        group.setRecord(reclist);
        group.setStuList(students);
        group.setTeacherList(teachers);
        return gr.save(group);
    }
}
